package org.glorylight.hacks.social.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.glorylight.hacks.social.data.UserNetworkData;
import org.glorylight.hacks.social.model.UserNetwork;
import org.glorylight.hacks.social.util.ModelHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
public class UserNetworkService extends BaseService {
	private static final Logger log = LoggerFactory.getLogger(UserNetworkService.class);
	
	@Transactional(readOnly = false)
	public void addNetwork(UserNetworkData data) throws Exception {
		if (log.isDebugEnabled())
			log.debug("add new network for: {} to: {}", new Object[] {data.getUser().getEmailAddress(), data.getConnectTo()});
		add(ModelHelper.convertUserNetworkData(data));
	}
	
	@Transactional(readOnly = false)
	public void deleteNetwork(UserNetworkData data) throws Exception {
		if (log.isDebugEnabled())
			log.debug("delete book for: " + data.getId());
		UserNetwork userNetwork = findNetwork(data.getId());
		delete(userNetwork);
	}

	private UserNetwork findNetwork(UUID id) {
		if (log.isDebugEnabled())
			log.debug("retrieve book: " + id);
		return em.find(UserNetwork.class, id);
	}
	
	public UserNetworkData find(UUID id) {
		if (log.isDebugEnabled())
			log.debug("retrieve user: {}", id);
		UserNetwork net = findNetwork(id);
		if (net != null)
			return ModelHelper.convertUserNetwork(net);
		else
			return null;
	}

	public List<UserNetworkData> findAll() {
		if (log.isDebugEnabled())
			log.debug("find all user");
		List<UserNetwork> result = em.createQuery("from UserNetwork", UserNetwork.class).getResultList();
		List<UserNetworkData> datas = null;
		if (result.size() > 0){
			datas = new ArrayList<UserNetworkData>();
			for (UserNetwork u : result)
				datas.add(ModelHelper.convertUserNetwork(u));
		}
		
		return datas;
	}
	
	public List<UserNetworkData> findAllByUser(String userId) {
		if (log.isDebugEnabled())
			log.debug("find all UserNetworkData");
		List<UserNetwork> result = em.createNamedQuery("network-by-user", UserNetwork.class)
				.setParameter("userId", userId).getResultList();
		List<UserNetworkData> datas = null;
		if (result.size() > 0){
			datas = new ArrayList<UserNetworkData>();
			for (UserNetwork u : result)
				datas.add(ModelHelper.convertUserNetwork(u));
		}
		
		return datas;
	}
	
	public List<UserNetworkData> findFollower(String userId) {
		if (log.isDebugEnabled())
			log.debug("find all UserNetworkData");
		List<UserNetwork> result = em.createNamedQuery("network-find-follower", UserNetwork.class)
				.setParameter("userId", userId).getResultList();
		List<UserNetworkData> datas = null;
		if (result.size() > 0){
			datas = new ArrayList<UserNetworkData>();
			for (UserNetwork u : result)
				datas.add(ModelHelper.convertUserNetwork(u));
		}
		
		return datas;
	}
	
	private UserNetworkData findConnection(String userId, String friendId) {
		if (log.isDebugEnabled())
			log.debug("find connection");
		UserNetwork result = em.createNamedQuery("network-find-connection", UserNetwork.class)
				.setParameter("userId", userId)
				.setParameter("connectTo", friendId).getSingleResult();
		if (result != null)
			return ModelHelper.convertUserNetwork(result);
		
		return new UserNetworkData();
	}
	
	public void deleteConnection(String userId, String friendId) throws Exception {
		delete(findConnection(userId, friendId));
	}
	
	public List<UserNetworkData> findAllByUserDate(String userId, Date startDate, Date endDate) {
		if (log.isDebugEnabled())
			log.debug("find all UserNetworkData by user date");
		List<UserNetwork> result = em.createNamedQuery("network-by-user-date", UserNetwork.class)
				.setParameter("userId", userId)
				.setParameter("startDate", startDate)
				.setParameter("endDate", endDate).getResultList();
		List<UserNetworkData> datas = null;
		if (result.size() > 0){
			datas = new ArrayList<UserNetworkData>();
			for (UserNetwork u : result)
				datas.add(ModelHelper.convertUserNetwork(u));
		}
		
		return datas;
	}
	
	public List<UserNetworkData> findAllByDate(Date startDate, Date endDate) {
		if (log.isDebugEnabled())
			log.debug("find all network by date");
		List<UserNetwork> result = em.createNamedQuery("network-by-date", UserNetwork.class)
				.setParameter("startDate", startDate)
				.setParameter("endDate", endDate).getResultList();
		List<UserNetworkData> datas = null;
		if (result.size() > 0){
			datas = new ArrayList<UserNetworkData>();
			for (UserNetwork u : result)
				datas.add(ModelHelper.convertUserNetwork(u));
		}
		
		return datas;
	}
}
